import json
from django.db import transaction
from django.http import JsonResponse
from rest_framework.views import APIView
from frame_server.jwt import CustomRefreshToken
from rest_framework_simplejwt.tokens import RefreshToken
from rest_framework_simplejwt.settings import api_settings
from django.contrib.auth import get_user_model, authenticate, login, logout
from utils.codeImg import ValidCodeImg
from utils.utils import validateError, responseSuccess, responseError, MyPaginator, filterFields, serializerJSON
from .serializers import ListSerializer, DetailSerializer, LoginInfoSerializer, InfoSerializer
from .validate import LoginValidate, AddUserValidate, EditUserValidate, UnlockValidate, ResetPasswordValidate, GrantValidate, UpdateInfoValidateBase, UpdatePasswordValidateBase
User = get_user_model()

# 登陆
class LoginAPI(APIView):
    def post(self,req):
        data = json.loads(req.body)
        validate = LoginValidate(data=data, context={"req":req})
        if validate.is_valid():
            user = authenticate(username=validate.data['username'], password=validate.data['password'])
            if user:
                login(req, user)
                data = LoginInfoSerializer(user).data# 生成 JWT 令牌
                refresh = CustomRefreshToken.for_user(user)
                data.update({
                    "token": str(refresh.access_token),
                    "refreshToken": str(refresh)
                })
                return JsonResponse(responseSuccess(data), safe=False)
            return JsonResponse(responseError('账号或密码错误'), safe=False)
        errs = validateError(validate.errors)
        return JsonResponse(responseError(errs), safe=False)

# 退出登陆    
class LogoutAPI(APIView):
    def get(self,req):
        logout(req)
        if api_settings.ROTATE_REFRESH_TOKENS and api_settings.BLACKLIST_AFTER_ROTATION:
            # 启用黑名单功能才需要执行
            if refresh_token := req.query_params.get('refresh_token', None):
                token = RefreshToken(refresh_token)
                token.blacklist()  # 将 refresh_token 加入黑名单
        return JsonResponse(responseSuccess(), safe=False)

# 获取用户信息
class InfoAPI(APIView):
    def get(self,req):
        serializer = InfoSerializer(req.user).data
        return JsonResponse(responseSuccess(serializer), safe=False)

# 用户专用更新用户信息（不需要传递用户id）
class UpdateInfoAPI(APIView):
    def post(self,req):
        data = req.data
        if not req.user.is_authenticated:
            return JsonResponse(responseError('请先登录'), safe=False)
        validate = UpdateInfoValidateBase(req.user, data=data)
        if validate.is_valid():
            validate.update(req.user, validate.validated_data)
            return JsonResponse(responseSuccess(), safe=False)
        # 格式化错误信息
        arr = validateError(validate.errors)
        return JsonResponse(responseError(arr), safe=False)

# 修改当前用户密码
class UpdatePasswordAPI(APIView):
    def post(self, req):
        data = req.query_params
        validate = UpdatePasswordValidateBase(data=data, context={'user':req.user})
        if validate.is_valid():
            validate.updatePassword(validate.validated_data)
            return JsonResponse(responseSuccess(), safe=False)
        err = validateError(validate.errors)
        return JsonResponse(responseError(err), safe=False)
    
# 图片验证码
class CaptchaAPI(APIView):
    def get(self,req):
        d, base64,code = ValidCodeImg().getValidCodeImg()
        req.session['code'] = code
        return JsonResponse(responseSuccess(base64), safe=False)

# 系统管理-用户管理-表格数据
class ListAPI(APIView):
    def get(self, req):
        queryDict = req.query_params.dict()
        filterDict = filterFields(User, queryDict, allow=['deptId'])
        if filterDict.get("deptId"):
            # 连表查询关联指定部门的所有用户
            filterDict['userdept__dept_id'] = int(filterDict.pop('deptId'))
        users = User.objects.filter(**filterDict)
        paginator = MyPaginator(users, **queryDict)
        serializers = ListSerializer(paginator.object_list, many=True)
        datas = serializerJSON(serializers)
        data = paginator.data(datas)
        return JsonResponse(responseSuccess(data), safe=False)

# 系统管理-用户管理-用户详情
class DetailAPI(APIView):
    def get(self, req):
        data = req.query_params
        id = data.get("id")
        if not id:
            return JsonResponse(responseError('id不能为空'), safe=False)
        if not User.objects.filter(id=int(id)).exists():
            return JsonResponse(responseError('用户不存在'), safe=False)
        user = User.objects.get(id=int(id))
        data = DetailSerializer(user).data
        return JsonResponse(responseSuccess(data), safe=False)

# 系统管理-用户管理-新增/编辑用户
class SubmitAPI(APIView):
    def post(self,req):
        data = req.data
        edit_id = data.get('id')
        if edit_id:
            obj = User.objects.get(id=int(edit_id))
            form = EditUserValidate(obj, data=data)
        else:
            form = AddUserValidate(data=data, context={"req":req})
        if not form.is_valid():
            # 格式化错误信息
            arr = validateError(form.errors)
            return JsonResponse(responseError(arr), safe=False)
        with transaction.atomic():
            if edit_id:
                obj = form.update(obj, form.validated_data)
            else:
                obj = form.create(form.validated_data)
        return JsonResponse(responseSuccess(str(obj.pk)), safe=False)

# 系统管理-用户管理-删除用户
class RemoveAPI(APIView):
    def post(self,req):
        ids = req.query_params.dict().get('ids')
        if not ids:
            return JsonResponse(responseError('缺少参数'), safe=False)
        ids = ids.split(',')
        if not User.objects.filter(id__in=ids).exists():
            return JsonResponse(responseError('删除对象不存在'), safe=False)
        result = User.objects.filter(id__in=ids).delete()
        if result:
            return JsonResponse(responseSuccess(), safe=False)
        return JsonResponse(responseError('删除失败'), safe=False)

# 系统管理-用户管理-账号解封
class UnlockAPI(APIView):
    def post(self, req):
        data = req.query_params
        validate = UnlockValidate(data=data)
        if validate.is_valid():
            validate.update(validate.validated_data)
            return JsonResponse(responseSuccess(), safe=False)
        err = validateError(validate.errors)
        return JsonResponse(responseError(err), safe=False)

# 系统管理-用户管理-重置密码
class ResetPasswordAPI(APIView):
    def post(self, req):
        data = req.query_params
        validate = ResetPasswordValidate(data=data)
        if validate.is_valid():
            validate.update(validate.validated_data)
            return JsonResponse(responseSuccess(), safe=False)
        err = validateError(validate.errors)
        return JsonResponse(responseError(err), safe=False)

# 系统管理-用户管理-给用户分配角色
class GrantAPI(APIView):
    def post(self, req):
        data = req.query_params.dict()
        validate = GrantValidate(data=data)
        if not validate.is_valid():
            err = validateError(validate.errors)
            return JsonResponse(responseError(err), safe=False)
        with transaction.atomic():
            validate.create(validate.validated_data)
        return JsonResponse(responseSuccess(), safe=False)